from scipy.cluster.hierarchy import linkage     #导入linage函数用于层次聚类
from scipy.cluster.hierarchy import dendrogram  #dendrogram函数用于将聚类结果绘制成树状图
from scipy.cluster.hierarchy import fcluster    #fcluster函数用于提取出聚类的结果
from sklearn.datasets import make_blobs         #make_blobs用于生成聚类算法的测试数据
from sklearn.cluster import AgglomerativeClustering  #自底向上层次聚类算法
import matplotlib.pyplot as plt                 #导入matplotlib绘图工具包
import xlrd
import numpy as np

def excel2m(path):#读excel数据转为矩阵函数
    data = xlrd.open_workbook(path)
    table = data.sheets()[0] # 获取excel中第一个sheet表
    nrows = table.nrows  # 行数
    ncols = 2  # 列数
    datamatrix = np.zeros((nrows, ncols))
    for x in range(ncols):
        cols = table.col_values(x)
        cols1 = np.matrix(cols)  # 把list转换为矩阵进行矩阵操作
        datamatrix[:, x] = cols1 # 把数据进行存储
    return datamatrix


#生成测试数据
X = excel2m("D:\服创\数数数学学学建建建模模模\鸢尾花降维后数据.xlsx");
plt.figure(figsize=(5, 4)) # 设置图片的大小
plt.scatter(X[:, 0], X[:, 1], c='b')  # 生成散点图
plt.show()
#from scipy.cluster.hierarchy import linkage

#层次聚类实现
#from scipy.cluster.hierarchy import dendrogram
model = linkage(X,  method='ward', metric='euclidean')
print(model.shape)
print(model[: 5])

#画出树状图
#from scipy.cluster.hierarchy import fcluster
plt.figure(figsize=(5, 4))
dendrogram(model, truncate_mode='lastp', p=20, show_leaf_counts=False, leaf_rotation=90, leaf_font_size=15,
           show_contracted=True)
plt.show()

# 根据临界距离返回聚类结果
d = 15
labels_1 = fcluster(model, t=d, criterion='distance')
print(labels_1[: 100])  # 打印聚类结果
print(len(set(labels_1)))  # 看看在该临界距离下有几个 cluster

# 根据聚类数目返回聚类结果
k = 3
labels_2 = fcluster(model, t=k, criterion='maxclust')
print(labels_2[: 100])
list(labels_1) == list(labels_2)  # 看看两种不同维度下得到的聚类结果是否一致

# 聚类的结果可视化，相同的类的样本点用同一种颜色表示
plt.figure(figsize=(5, 4))
plt.scatter(X[:, 0], X[:, 1], c=labels_2, cmap='prism')
plt.show()

